package com.fy56.platform.logistics.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.beanutils.BeanUtilsBean;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;

/**
 * 转型工厂
 */
public class BeanTransitionShopUtil {// 前 BeanUtils

    public static void getBeanUtilsBean(Object obj1, Object obj2){
        try {
            BeanUtilsBean beanUtilsBean = new BeanUtilsBean();
            beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.BigDecimalConverter(null), BigDecimal.class);
            beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.DateConverter(null), Date.class);
            beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.SqlTimestampConverter(null), java.sql.Timestamp.class);
            beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.sql.Date.class);
            beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.SqlTimeConverter(null), java.sql.Time.class);
            beanUtilsBean.getConvertUtils().register(new org.apache.commons.beanutils.converters.IntegerConverter(null), Integer.class);
            if(obj2 != null){
                beanUtilsBean.copyProperties(obj1, obj2);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*------------------------------------------------------------------------------------------------*/

    /**
     * 辅助功能：根据数据列名,构造属性名
     * @param str
     * @return
     */
    private static String createPropertyName(String str) {
        if(str.indexOf("_")>=0){
            str = str.toLowerCase();

            char[] ch = str.toCharArray();
            for (int i=0; i<ch.length-1; i++) {
                if(ch[i] == '_'){
                    ch[i+1] = (char)(ch[i+1] - 32);
                }
            }
            String val = new String(ch);
            val = val.replace("_","");
            return val;
        }else{
            return str;
        }
    }

    public static Object convertMap(Class<?> type, Map<String, ?> entity){
        try {
            //[重构]Map信息
            HashMap<String, Object> model = new HashMap<String, Object>();
            for (String keyName : entity.keySet()) {
                model.put(createPropertyName(keyName), entity.get(keyName));
            }
            //[获取]类属性
            BeanInfo beanInfo = Introspector.getBeanInfo(type);
            //[创建]JavaBean对象
            Object obj = type.newInstance();
            //[赋值]给JavaBean对象的属性
            PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();
            for (int i = 0; i< propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                //[获取]属性名
                String propertyName = descriptor.getName();
                //[判断]属性名在Map中是否存在
                if (model.containsKey(propertyName)) {
                    // 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
                    try {
                        Object value = model.get(propertyName);
                        if("class java.lang.Integer".equals(String.valueOf(descriptor.getPropertyType()))){
                            if(value!=null)
                                descriptor.getWriteMethod().invoke(obj, Integer.parseInt(String.valueOf(value)));
                        }else if("class java.lang.String".equals(String.valueOf(descriptor.getPropertyType()))){
                            if(value!=null)
                                descriptor.getWriteMethod().invoke(obj, String.valueOf(value));
                        }else{
                            if(value!=null)
                                descriptor.getWriteMethod().invoke(obj, value);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Object();
    }

    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null)
            return null;

        Map<String, Object> map = new HashMap<String, Object>();

        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor property : propertyDescriptors) {
            String key = property.getName();
            if (key.compareToIgnoreCase("class") == 0) {
                continue;
            }
            Method getter = property.getReadMethod();
            Object value = getter != null ? getter.invoke(obj) : null;
            map.put(key, value);
        }

        return map;
    }

    public static Map<String, Object> entityToMap(Map<String, ?> entity) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        for (String key : entity.keySet()) {
            if(key.contains("_")){
                map.put(createPropertyName(key), entity.get(key));
            }else{
                map.put(key, entity.get(key));
            }
        }
        return map;
    }

    /*------------------------------------------------------------------------------------------------*/

    /**
     * json字符串<转化为>对象实体
     * @param json
     * @param classOfT
     * @return
     */
    public static <T> T sto(String json, Class<T> classOfT) {
        if(null == json || json.length() == 0){
            return null;
        }
        return JSONObject.toJavaObject(JSON.parseObject(json), classOfT);
    }

    /**
     * 实体对象<转化为>json字符串
     * @param src
     */
    public static String ots(Object src){
        return JSONObject.toJSONString(src);
//		Gson gson = new Gson();
//		return gson.toJson(src);
    }

    /**
     * json字符串<转化为>Map
     * @param json
     * @return
     */
    public static Map<String, Object> jsonToMap(String json) {
        Map<String, Object> map = new LinkedHashMap<>();

        JSONObject jsonObject = JSON.parseObject(json);
        Collection<String> it = jsonObject.keySet();
        for (String key : it) {
            String u = jsonObject.get(key).toString();
            map.put(key, u);
        }
        return map;
    }
}